home *** CD-ROM | disk | FTP | other *** search
- KB_SEG SEGMENT AT 40H ;ROM BIOS data area
- ORG 1AH ;Location of keyboard buffer
- KB_HEAD DW ? ;Buffer head
- KB_TAIL DW ? ;Buffer tail.
- KB_BUFFER DW 16 DUP (?) ;Actual keyboard buffer
- KB_BUFFER_END LABEL WORD ;Two bytes past end of buffer
- KB_SEG ENDS
-
- CODE_SEG SEGMENT
-
- TRUE = 1 ;Pseudo-Ops
- FALSE = 0
-
- ASSUME CS:CODE_SEG
- ORG 100H ;A Com file
-
- BEGIN: JMP INITIALIZE ;Skip data and Interrupt routine
-
- COPYRIGHT DB 'Author Mark Boatright; Copyright 1985'
-
- TST_FLG DB ?
-
- COMMAND_KEYS DW 5400H ;SHIFT F1 300,7,E,1
- DW 5500H ;SHIFT F2 300,8,N,1
- DW 5600H ;SHIFT F3 1200,7,E,1
- DW 5700H ;SHIFT F4 1200,8,N,1
- DW 5800H ;SHIFT F5 2400,7,N,1
- DW 5900H ;SHIFT F6 2400,8,N,1
-
- ;DATA_8250A stored in this format LSB, MSB, and a byte for parity,length and
- ;stopbit
-
- DATA_8250A DB 75H,01H,1AH ;300,E,7,1
- DB 75H,01H,07H ;300,N,8,1
- DB 5DH,00H,1AH ;1200,E,7,1
- DB 5DH,00H,07H ;1200,N,8,1
- DB 2FH,00H,1AH ;2400,E,7,1
- DB 2FH,00H,07H ;2400,N,8,1
-
- MESSAGE DB 'JR Communications Kludge installed. (C) 1985 by '
- DB 'Mark Boatright'
- DB 0DH,0AH,'(For built in serial port, will not address internal '
- DB 'modem.)'
- DB 0DH,0AH
- DB 0DH,0AH,' COMMANDS'
- DB 0DH,0AH
- DB 0DH,0AH,'SHIFT F1 300,E,7,1 SHIFT F2 300,N,8,1'
- DB 0DH,0AH,'SHIFT F3 1200,E,7,1 SHIFT F4 1200,N,8,1'
- DB 0DH,0AH,'SHIFT F5 2400,E,7,1 SHIFT F6 2400,N,8,1'
- DB 0DH,0AH
- DB 0DH,0AH,' INSTRUCTIONS'
- DB 0DH,0AH
- DB 0DH,0AH,'1. Load Communications Program.'
- DB 0DH,0AH,'2. Use one of the kludge commands to set your comm parms.'
- DB 0DH,0AH
- DB 0DH,0AH,'NOTE: You may need to set comm parms with the '
- DB 'communications program first, '
- DB 0DH,0AH,' then use kludge.'
- DB 0DH,0AH
- DB 0DH,0AH,'NOTE: A few programs (most do not) address built in port '
- DB 'as COM2.'
- DB 0DH,0AH,' In that event adjust program defalts accordingly'
- DB 0DH,0AH
- DB 0DH,0AH,'NOTE: This version of kludge will not help with dialing '
- DB 'directory problems.'
- DB 0DH,0AH,' Dial from keyboard.'
- DB 0DH,0AH
- DB 0DH,0AH,'EXPERIMENT. GOOD LUCK!!'
- DB 0H
-
-
- ROM_KB_INT_9 DD 1 ;Should be location of ROM INT 9
- ;routine
-
- RESIDENT_MAINLINE PROC NEAR ;OK, someone's pressed a key.
- PUSH DS ;Save what we use
- PUSH SI
- PUSH DX
- PUSH CX
- PUSH BX
- PUSH AX
- PUSHF ;For ROM_KB_INT_9 IRET
- ;IRET will pop them off stack.
- CALL ROM_KB_INT_9 ;Put the key in buffer
-
- ASSUME DS:KB_SEG ;We need data from this segment
- MOV AX,KB_SEG
- MOV DS,AX
-
-
- CALL FIND_CHAR ;find char in buffer, if any
- CMP TST_FLG,TRUE ;if char valid TST_FLG returns true
- JNE EXIT_MAINLINE ;Not true, we leave
- CALL KEY_CHECK ;Is the character a command key?
- CMP TST_FLG,TRUE ;Result of check in TST_FLG
- JNE EXIT_MAINLINE ;If not a command then exit
- CLI ;Shucks, JR keyboard is NMI, oh well
- CALL LOOK_UP ;Where's the data for the command?
- CALL BYTES_OUT ;Reset 8250A to proper JR parms
-
-
-
- EXIT_MAINLINE:
-
- POP AX ;restore registers
- POP BX
- POP CX
- POP DX
- POP SI
- POP DS
- STI
- IRET ;return for terminate but stay resident
-
- RESIDENT_MAINLINE ENDP
-
- FIND_CHAR PROC NEAR
- ;On exit BX should point to character
-
- MOV TST_FLG,FALSE
- MOV BX,KB_TAIL
- CMP BX,KB_HEAD ;HEAD=TAIL then no valid character
- JNE VALID_CHAR
- RET ;and we return with TST_FLG=FALSE
- VALID_CHAR:
- MOV TST_FLG,TRUE ;We know we've got a character
- SUB BX,2 ;Try and move back a couple of bytes
- ;from kb_tail, if we're still in the
- ;buffer this will be location of char.
- CMP BX,OFFSET KB_BUFFER ;Are we still in the buffer?
- JB WRAP ;No, we'd better wrap
- RET ;We're OK, let's go back
- WRAP:
- MOV BX,OFFSET KB_BUFFER_END ;Wrap around the buffer queue
- SUB BX,2
- RET ;We're OK now, let's return
- FIND_CHAR ENDP
-
- KEY_CHECK PROC NEAR
- ;On entry BX points to character in buffer.
- ;On exit TST_FLG returns status of check (true/false).
- ;If TST_FLG true, then CX contains the number of the command.
-
- MOV TST_FLG,FALSE ;Assume char not a command key
- MOV AX,[BX] ;Put the character in AX
- LEA SI,COMMAND_KEYS ;Put starting address in SI
- MOV CX,6 ;Put no. of command keys in CX
-
- CHECK:
- CMP AX,CS:[SI] ;Is char a command key?
- JE MATCH ;Yes, jump out.
- ADD SI,2 ;Address of next command key
- LOOP CHECK ;Do it again
- RET ;No Match found.
- MATCH: ;OK, we've got a match.
- MOV TST_FLG,TRUE ;So Resident_Mainline knows we found
- ;match
- MOV KB_TAIL,BX ;Since it's a command key we'll take
- ;this character out of buffer
-
- NEG CX ;This gives us relative positioh
- ADD CX,6 ;of command key... in CX.
- RET
-
- KEY_CHECK ENDP
-
- LOOK_UP PROC NEAR
- ;On entry CX contains no.(relative to position) of command
- ;On exit SI has starting address of relevant 8250A data
-
- MOV AX,CX ;Put no. of command in AX
- MOV CX,3 ;And multiply it by number of
- MUL CL ;bytes in 8250A_DATA/no. of
- ;command keys. This = 3.
- LEA SI,DATA_8250A ;Starting address in SI
- ADD SI,AX ;Starting address of data we want
- RET ;We've got our address
- LOOK_UP ENDP
-
- BYTES_OUT PROC NEAR
- ;For better understanding of what this routine does see the JR Tech Ref
- ;section on the serial port.
- ;On entry SI should contain the starting adress of data (DATA_8250A).
- ;Data arranged in this format
- ;1. a byte for MSB of baud rate divisor
- ;2. a byte for LSB of baud rate divisor
- ;3. a byte to set other comm parms--stopbit, wordlength, parity
-
- MOV DX,2FBH ;Line Control register address
- MOV AL,10000000B ;Must set DLAB (Divisor Latch Address
- ;Byte) high. Bit 7 = 1.
- OUT DX,AL ;to access divisor latches LSB and MSB
- JMP SHORT KT1 ;As per JR Tech Ref... We stick in
- ;these jumps to avoid back to back
- ;I/0 operations to 8250A and accomodate
- ;the 8250A read/write cycle time.
- KT1: MOV DX,2F8H ;Address baud rate divisor LSB
- MOV AX,CS:[SI] ;The LSB
- OUT DX,AL
- JMP SHORT KT2 ;Kill time.
- KT2: INC SI ;To next byte of data
- MOV DX,2F9H ;Address baud rate divisor, MSB
- MOV AX,CS:[SI] ;The MSB
- OUT DX,AL
- JMP SHORT KT3 ;Kill time.
- KT3: INC SI ;To next byte of data
- MOV DX,2FBH ;Address line control register
- MOV AX,CS:[SI] ;The other Comm parms
- OUT DX,AL ;DLAB should now be low again.
- JMP SHORT KT4 ;Kill time.
- KT4: MOV DX,2F8H ;As per JR Tech Ref, writing to
- ;line control register may have
- IN AL,DX ;caused data ready to go high
-
- RET ;don't want to forget this
-
- BYTES_OUT ENDP
-
- INITIALIZE PROC NEAR
- CALL GET_VECTOR
- CALL INSTALL_VECTOR
- CALL CLEAR_BUFFER
- CALL MESSAGE_OUT
-
- MOV DX,OFFSET INITIALIZE ;for terminate/stay resident
- INT 27H ;Terminate/stay resident
- INITIALIZE ENDP
-
- GET_VECTOR PROC NEAR
- ;We'll use DOS function 35H, vector received in ES:BX pair
-
- MOV AL,9H ;we want vector for interrupt 9
- MOV AH,35H ;For DOS get interrupt vector function
- INT 21H ;invoke the function
- MOV WORD PTR ROM_KB_INT_9,BX
- MOV WORD PTR ROM_KB_INT_9[2],ES
- RET
-
- GET_VECTOR ENDP
-
- INSTALL_VECTOR PROC NEAR
-
- ASSUME DS:CODE_SEG ;for function 25H
- PUSH CS ;We send out vector we want
- POP DS ;to install in DS:DX pair
- MOV DX, OFFSET RESIDENT_MAINLINE
- CLI
- MOV AH,25H ;Use DOS function 25H to make
- MOV AL,9H ;INT 9 vector point to our
- INT 21H ;routine.
- STI
- RET
- INSTALL_VECTOR ENDP
-
- CLEAR_BUFFER PROC NEAR ;clears the keyboard buffer
- ASSUME DS:KB_SEG
- MOV AX,KB_SEG
- MOV DS,AX
- MOV BX,OFFSET KB_BUFFER ;Head and Tail set equal to
- MOV KB_HEAD,BX ;first byte of buffer.
- MOV KB_TAIL,BX ;Head = Tail so buffer cleared
- RET
- CLEAR_BUFFER ENDP
-
- MESSAGE_OUT PROC NEAR
- ASSUME DS:CODE_SEG
- PUSH CS
- POP DS
- LEA SI,MESSAGE
- MOV AH,2 ;For Dos Standard Output function
- MESS_OUT:
- MOV DL,[SI] ;Get a byte
- CMP DL,0 ;Done?
- JE MESS_OUT_DONE ;YES, jump out of loop.
- INT 21H ;No, send out the byte
- INC SI ;Point SI at next byte
- JMP MESS_OUT ;Do it again
- MESS_OUT_DONE:
- RET
- MESSAGE_OUT ENDP
-
- CODE_SEG ENDS
- END BEGIN ;Tell Dos where to start when it
- ;loads program.